home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
tex
/
itrns211.zip
/
SRC
/
ICHAR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-13
|
15KB
|
464 lines
/*
*==========================================================================
* Copyright 1991 Avinash Chopde, All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Avinash Chopde not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission.
* Avinash Chopde makes no representations about the suitability of this
* software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* AVINASH CHOPDE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
* IN NO EVENT SHALL AVINASH CHOPDE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*
* Author: Avinash Chopde, 1991
* C2 Colonial Drive #4, Andover, MA 01810, USA.
*
*/
#include "itrans.h"
static char S_RCSID[] = "$Header: e:/itrans/src/rcs/ichar.c 1.4 91/10/13 16:49:34 avinash Exp $";
/* =================================================================== */
static int S_get_cus_form(font_t* fptr, /* the font data structure to use */
letter_t dlet, /* letter searched for */
comp_unit_t** cus, /* will return a pointer to the cus here */
comp_unit_t** imp, /* will return implicit char creation ptr */
int* lastform,
int* lastlig); /* whether last two cons have a ligature */
static int S_add_cus(pschar_t psfm[], comp_unit_t* pcu, comp_unit_t cu);
/* =================================================================== */
/* Handle a letter (possibly complex) */
/******
(font_t* fptr, the font data structure to use
letter_t dlet, letter to convert
comp_unit_t pcus[], the comp units that make this
letter - all u_pschar are valid
PostScript codes, or NO_PSCHAR
int size_pcus, array size of ecus- number of elements
int *ox, int *oy, the orgin of this letter
int *width) the width of this complete letter
********/
int make_letter(font_t* fptr,
letter_t dlet,
comp_unit_t pcus[],
int size_pcus,
int *ox, int *oy,
int *width)
{
int num_pcus; /* number of postscript chars that were added to pcus */
int pcode;
comp_unit_t* lcus; /* comp units that make the form of
* the given letter dlet
*/
comp_unit_t* icus; /* comp units that make the implicit form
* of the given letter dlet
*/
comp_unit_t* startcus;
letter_t rcons; /* for recursive calls */
int x1, y1, w, i, j, c1, c2, lastform, nolig, lastlig;
num_pcus = 0;
*ox = *oy = 0;
*width = 0;
x1 = y1 = w = 0;
#ifdef DEBUG
fprintf(stderr, "in make_letter\n");
#endif
if (!S_get_cus_form(fptr, dlet, &lcus, &icus, &lastform, &lastlig)) {
/* some error, illegal char, incomplete fptr
* data structure, etc
*/
return 0; /* 0 elements added */
}
/* collect all the PS chars in lcus into the output array */
while (lcus) {
/* get the PS code of this unit */
pcode = lcus->u_pschar;
#ifdef DEBUG
fprintf(stderr, "while lcus in make_letter: pcode is %d\n", pcode);
#endif /*DEBUG*/
if (pcode == NO_PSCHAR || (pcode >= 0 && pcode <= 255)) {
/* valid PostScript code */
num_pcus += S_add_cus(fptr->psfm, &pcus[num_pcus], *lcus);
/* update origin and width */
/* XXX need to track bounding boxes etc */
} else if (pcode == IMPLICIT_PSCHAR && icus) {
/* Need to use the implicit char description, and have a
* valid pointer to comp_units that compose the implicit
* char.
*/
startcus = icus;
while (startcus) {
#ifdef DEBUG
fprintf(stderr, "while startcus in make_letter: pcode is %d\n", pcus[num_pcus-1].u_pschar);
#endif /*DEBUG*/
/* error check */
if ( startcus->u_pschar != NO_PSCHAR &&
(startcus->u_pschar < 0 || startcus->u_pschar > 255)) {
fprintf(stderr, "ERROR: %d illegal pschar in implicit comp units\n", startcus->u_pschar);
} else {
num_pcus += S_add_cus(fptr->psfm,&pcus[num_pcus],*startcus);
}
startcus = startcus->next;
}
} else if (pcode == IMPLICIT_PSCHAR) {
/* implies that no implicit char defined for this letter, and
* the letter is complex, and has to be split into
* simpler parts
* The way it is done is that every consonant is
* printed out in HALF_FORM, except the last
* consonant, which is printed out in its IMPLICIT_FORM.
************
* What to do here is driven by the CONSONANTS_MANY case
* in S_get_cus_root()
* Of course, be careful, this could also be CONS..DOUBLE...
* in case the IFM file contains SAME_AS CCS statements
* but no implicit char defns...
*/
#ifdef DEBUG
fprintf(stderr, "make_letter: pcode IMPLICIT, no icus, looping for halfforms\n");
#endif /*DEBUG*/
for (i = 0; i < dlet.n; i ++) {
#ifdef DEBUG
fprintf(stderr, "make-letter i %d dlet.n %d lastlig %d\n", i, dlet.n, lastlig);
#endif
/* check if a ligature has been defined for
* (current char, next char) pair, use it if available
*/
if (i < (dlet.n-1)) { /* i.e, two more consonants left..*/
c1 = _I_(dlet.cons[i]); c2 = _I_(dlet.cons[i+1]);
if (i == (dlet.n-1)) j = lastform; /* last chars */
else j = HALF_FORM; /* still more to come,so use halfform*/
nolig = ((dlet.nolig[i]) || (lastlig && i == (dlet.n-3)));
#ifdef DEBUG
fprintf(stderr, "makeletter nolig %d\n", nolig);
#endif
/* if last lig exists, do not use the
* secondlast consonant with the thirdlast consonant.
* -- just display the thirdlast consonant in
* half form.
*/
if (!nolig && fptr->ligatures[c1][c2].cus &&
fptr->ligatures[c1][c2].cus[IMPLICIT_FORM]) {
/* just check for existence of the IMPLICIT_FORM-
* if it exists, the half-form will also
* exist---other way around is not true!.
*/
#ifdef DEBUG
fprintf(stderr, "C1: %d, C2 %d, cus(%d)\n", c1, c2,
fptr->ligatures[c1][c2].cus[j]);
#endif /*DEBUG*/
/* found ligature! */
if (i == (dlet.n-2)) j = lastform; /* last chars */
else j = HALF_FORM; /* more to come,so use halfform*/
rcons.n = 2; rcons.v = j;
rcons.type = CONSONANT_DOUBLE_TYPE;
rcons.cons[0] = dlet.cons[i];
rcons.cons[1] = dlet.cons[i+1];
rcons.nolig[0] = FALSE;
i++; /* have used up next char too */
} else {
/* no ligature defined, draw a half form */
rcons.n = 1; rcons.v = HALF_FORM;
rcons.type = CONSONANT_SINGLE_TYPE;
rcons.cons[0] = dlet.cons[i];
}
} else { /* this is the last char */
rcons.n = 1; rcons.v = lastform;
rcons.type = CONSONANT_SINGLE_TYPE;
rcons.cons[0] = dlet.cons[i];
}
j = make_letter(fptr, rcons, &pcus[num_pcus],
size_pcus - num_pcus, &x1, &y1, &w);
/* recompute origin, width */
num_pcus += j;
}
} else { /* ERROR */
fprintf(stderr, "ERROR ERROR: %d illegal pschar in Form comp units\n", pcode);
}
lcus = lcus->next;
} /* while (lcus) */
#ifdef DEBUG
fprintf(stderr, "make_letter::created CUS containging %d cus\n", num_pcus);
#endif /*DEBUG*/
/* keep the next pointers in the pcus correct */
for (i = 0; i < num_pcus; i ++) {
pcus[i].next = &pcus[i+1];
}
if (num_pcus > 0) pcus[num_pcus-1].next = NULL;
return num_pcus;
} /* make_letter() */
/* =================================================================== */
static comp_unit_t S_implicit_cu = {IMPLICIT_PSCHAR, 0, 0, 0, NULL};
stat